//
//  main.m
//  07-内存管理
//
//  Created by dllo on 16/7/12.
//  Copyright © 2016年 dllo. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
  
    // 内存问题
    // 一. 内存溢出(泄露)
    //    内存过多导致溢出, 产生Crash
    // 二. 野指针(过度释放)
    //    指针指向未知区域(指向一块被释放的内存)
    // 内存管理方式
    // 1.垃圾回收机制:只有Mac上有
    
    // IOS
    // 2.MRC: 手动管理引用计数
    // 3.ARC: 自动管理引用计数(现在常用)
    // ARC 基于MRC 进行管理, 系统帮助程序员添加了内存管理的内容
    
    // retain alloc copy 需要进行内存管理
    // 内存管理: 引用计数(计数器)
    // 有retain alloc copy 会对引用计数 +1
    // 有release autorelease 会对引用计数 -1
    // 当对象的计数器为0的时候,系统会调用对应的dealloc方法
    
    // 注意: 内存管理, 对对象操作完成后, 在进行释放
    Person *per = [[Person alloc] init];
    NSLog(@"%ld", per.retainCount);
    [per retain];
    [per release];
    NSLog(@"%ld", per.retainCount);
        
    // 集合类型, 会对对象进行引用计数
    // addObject 对 对象进行引用计数 +1
    // removeObject 对 对象进行引用计数 -1
    NSMutableArray *array = [NSMutableArray arrayWithObjects:per, nil];
    NSLog(@"添加到数组后:%ld", per.retainCount);
    [array removeAllObjects];
    NSLog(@"从数组中移除后:%ld", per.retainCount);
    
    // ARC    (语义特性)
    // strong (ARC, 强引用,引用计数 +1) weak(应用于对象类型(NSObjeect子类),弱引用,对象被释放时,会自动置空)
    // retain (MRC,强引用,引用计数 +1)
    // copy (拷贝, 把对象拷贝一份, 原来的引用计数不变, 新的 +1)
    // assign (应用于简单的数据类型,不会产生引用计数)
        
    // 协议
    // 1. 声明协议,声明协议方法
    // 2. 签订协议
    // 3. 实现协议方法
    
    // 如果想实现对象的拷贝(不论是深拷贝,还是浅拷贝)
    // 1.签订协议NSCopying
    // 实现协议方法copyWithZone
    Person *per1 = [per copy];
    NSLog(@"新person:%@ 旧person:%@", per1, per);
    
    // KVC Key-Value-Coding 健值编码 间接访问成员的方式
    // valueForKey
    per.name = @"yinjiaen";
    per.sexual = @"men";
    id name = [per valueForKey:@"name"];
    NSLog(@"%@", name);
    [per setValue:@"zuoyue" forKey:@"name"];
    NSLog(@"%@", [per valueForKey:@"name"]);
    NSLog(@"%@", per.name);
    
    Person *per3 = [[Person alloc] init];
    per3.person = per;
    id name1 = [per3 valueForKeyPath:@"person.name"];
    NSLog(@"1111:%@", name1);
    [per3 release];
    [per3 setValue:@"fanzi" forKeyPath:@"person.name"];
    
    NSMutableDictionary *mdic = [NSMutableDictionary dictionary];
    [mdic setValue:@"sdf" forKey:@"name"];
    NSLog(@"%@", mdic);
    
    NSDictionary *dic2 = [[NSDictionary alloc] initWithObjectsAndKeys:@"123456879", @"id", @"dfsadfs", @"description", nil];
    Person *dicper = [[Person alloc] init];
    [dicper setValuesForKeysWithDictionary:dic2];
    // 加在Build phases下的编译source下
    // 如果在ARC工程下使用MRC的文件
    // -fno-objc-arc
    // 在MRC工程下使用ARC文件
    // -fobjc-arc
    
    return 0;
}
